package com.zhouheng.springbootmultithreading.common.utils;

import com.zhouheng.springbootmultithreading.common.exception.BaseException;

import java.math.BigDecimal;

/**
 * 计算工具类
 * 注意
 * 1.直接用double或者float运算会精度丢失
 * 2.float自动转double也会精度丢失，所以以下方法，不能用float入参
 * 3.出参这里也是Bigdecimal，因为我们具体业务中返回String，double，int的情况都有比较多
 *
 * @author 周恒
 * @date 20180725 17:54:40
 * @since v1.0
 */
public class BigdecimalUtil {

    private BigdecimalUtil(){

    }

    /**
     * BigDecimal 加法运算
     *
     * @param num1 描述此参数
     * @param num2 描述此参数
     * @return 返回 big decimal 描述此返回参数
     * @author 周恒
     * @date 20180628 16:42:24
     * @since v1.0
     */
    public static BigDecimal add(String num1, String num2){
        BigDecimal b1 = new BigDecimal(num1);
        BigDecimal b2 = new BigDecimal(num2);
        return b1.add(b2);
    }
    public static BigDecimal add(double num1,double num2){
        return add(String.valueOf(num1), String.valueOf(num2));
    }

    /**
     * BigDecimal 减法运算
     *
     * @param num1 描述此参数
     * @param num2 描述此参数
     * @return 返回 big decimal 描述此返回参数
     * @author 周恒
     * @date 20180628 16:42:48
     * @since v1.0
     */
    public static BigDecimal subtract(String num1,String num2){
        BigDecimal b1 = new BigDecimal(num1);
        BigDecimal b2 = new BigDecimal(num2);
        return b1.subtract(b2);
    }
    public static BigDecimal subtract(double num1,double num2){
        return subtract(String.valueOf(num1), String.valueOf(num2));
    }

    /**
     * BigDecimal 乘法运算
     *
     * @param num1 描述此参数
     * @param num2 描述此参数
     * @return 返回 big decimal 描述此返回参数
     * @author 周恒
     * @date 20180628 16:43:11
     * @since v1.0
     */
    public static BigDecimal multiply(String num1,String num2){
        BigDecimal b1 = new BigDecimal(num1);
        BigDecimal b2 = new BigDecimal(num2);
        return b1.multiply(b2);
    }
    public static BigDecimal multiply(double num1,double num2){
        return multiply(String.valueOf(num1), String.valueOf(num2));
    }

    /**
     * BigDecimal 除法运算
     *
     * @param num1 描述此参数
     * @param num2 描述此参数
     * @param scale 保留多少位小数
     * @return 返回 big decimal 描述此返回参数
     * @author 周恒
     * @date 20180704 14:43:11
     * @since v1.0
     */
    public static BigDecimal divide(String num1,String num2,int scale){
        if(scale<0){
            throw new BaseException("参数必须是正整数或零");
        }
        BigDecimal b1 = new BigDecimal(num1);
        BigDecimal b2 = new BigDecimal(num2);
        return b1.divide(b2,scale,BigDecimal.ROUND_HALF_UP);
    }
    public static BigDecimal divide(double num1,double num2,int scale){
        return divide(String.valueOf(num1), String.valueOf(num2), scale);
    }

    /**
     * 四舍五入
     *
     * @param num   降水数值
     * @param scale 需要保留的小数位
     * @return 返回 String（不会出现E）
     * @author 周恒
     * @date 20180704 15:25:39
     * @since v1.0
     */
    public static String doubleRoundHalfUp(String num, int scale){
        if(scale<0){
            throw new BaseException("参数必须是正整数或零");
        }
        String returnNum = new BigDecimal(num).setScale(scale,BigDecimal.ROUND_HALF_UP).toString();
        double returnD = Double.valueOf(returnNum);
        if(returnD == 0){
            return "0";
        }
        return returnNum;
    }

    public static Double doubleRoundHalfUp(Double num, int scale){
        if(scale<0){
            throw new BaseException("参数必须是正整数或零");
        }
        return new BigDecimal(num).setScale(scale,BigDecimal.ROUND_HALF_UP).doubleValue();
    }

}
